﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraReports.UI;
using OilDB;

namespace MainApp
{
    public partial class InOutReport : DevExpress.XtraEditors.XtraUserControl
    {
        Guid allStores = Guid.Empty;
        DataServices data = null;
        DataTable dataSource = new DataTable();
        List<Guid> productList = new List<Guid>();
        Dictionary<Guid, string> productNames = new Dictionary<Guid, string>();


        InOutPrintReport printReport = new InOutPrintReport();
        Dictionary<Guid, XRLabel> printHeaders = new Dictionary<Guid, XRLabel>();
        Dictionary<Guid, XRLabel> printHeadersLv2Nhap = new Dictionary<Guid, XRLabel>();
        Dictionary<Guid, XRLabel> printHeadersLv2LuyKe = new Dictionary<Guid, XRLabel>();
        Dictionary<Guid, XRLabel> printDataNhap = new Dictionary<Guid, XRLabel>();
        Dictionary<Guid, XRLabel> printDataLuyKe = new Dictionary<Guid, XRLabel>();

        public enum InOutReportType{
            InType, OutType, ReceiptType
        }

        InOutReportType reportType = InOutReportType.InType;

        public void setReportType(InOutReportType newType)
        {
            reportType = newType;
        }

        public InOutReportType getReportType()
        {
            return reportType;
        }

        private void setData(DataServices value)
        {
            data = value;
            updateProducts();
        }

        public DateTime? getBeginDate()
        {
            if (cbMonth.EditValue == null || cbYear.EditValue == null)
            {
                return null;
            }
            else
            {
                return new DateTime((int)cbYear.EditValue, (int)cbMonth.EditValue, 1);
            }
        }

        public DateTime? getEndDate()
        {
            if (cbMonth.EditValue == null || cbYear.EditValue == null)
            {
                return null;
            }
            else
            {
                DateTime r = new DateTime((int)cbYear.EditValue, (int)cbMonth.EditValue, 1);
                return r.AddMonths(1);
            }
        }
        
        public void UpdateReport()
        {
            string dateCol = "";
            DataTable staData = null;
            DateTime curr = new DateTime(1990, 6, 26);
            DataRow currRow = null;
            Dictionary<Guid, decimal> total = new Dictionary<Guid, decimal>();
            Guid product;
            string productName = "";
            Guid? store = null;
            
            if (getBeginDate() == null || data == null || cbStores.EditValue == null)
            {
                return;
            }

            if ((Guid)cbStores.EditValue != allStores)
            {
                store = (Guid)cbStores.EditValue;
            }
            switch (reportType)
            {
                case InOutReportType.InType:
                    data.ImportStatisticsEachDayAdapter.Fill(dataSetOilManagement.ImportStatisticsEachDay, getBeginDate(), getEndDate(), store);
                    staData = dataSetOilManagement.ImportStatisticsEachDay;
                    dateCol = "ImportDate";
                    break;
                case InOutReportType.OutType:
                    data.ExportStatisticsEachDayAdapter.Fill(dataSetOilManagement.ExportStatisticsEachDay, getBeginDate(), getEndDate(), store);
                    staData = dataSetOilManagement.ExportStatisticsEachDay;
                    dateCol = "ExportDate";
                    break;
                case InOutReportType.ReceiptType:
                    data.ReceiptStatisticsEachDayAdapter.Fill(dataSetOilManagement.ReceiptStatisticsEachDay, getBeginDate(), getEndDate(), store);
                    staData = dataSetOilManagement.ReceiptStatisticsEachDay;
                    dateCol = "ReceiptDate";
                    break;
                default:
                    break;
            }
            staData.TableName = "Statistics";
            gridReport.BeginUpdate();
            dataSource.Clear();

            decimal sumTotal = 0;
            foreach (Guid item in productList)
            {
                total[item] = 0;
            }
            foreach (DataRow row in staData.Rows)
            {
                if (curr != (DateTime)row[dateCol])
                {
                    curr = (DateTime)row[dateCol];
                    currRow = dataSource.NewRow();
                    currRow["Date"] = curr;                    
                    dataSource.Rows.Add(currRow);
                }
                product = (Guid)row["Product"];
                productName =productNames[product];
                currRow["Import" + productName] = row["TotalAmount"];
                total[product] += (decimal)row["TotalAmount"];
                sumTotal += (decimal)row["TotalAmount"];
                currRow["Total" + productName] = total[product];
                currRow["Total"] = sumTotal;
            }            
            gridReport.EndUpdate();
            //MessageBox.Show(dataSetOilManagement.ImportStatisticsEachDay.Rows.Count.ToString());
        }

        public DataServices Data { get { return data; } set { setData(value); } }

        public InOutReport()
        {
            InitializeComponent();
            cbMonth.Properties.Items.Clear();
            for (int i = 1; i <= 12; i++)
            {
                cbMonth.Properties.Items.Add(i);
            }
            cbYear.Properties.Items.Clear();
            for (int i = 1990; i <= 2060; i++)
            {
                cbYear.Properties.Items.Add(i);
            }            
        }

        public void updateStores()
        {
            dataSetOilManagement.Stores.Clear();
            dataSetOilManagement.Stores.AddStoresRow(allStores, "Tất cả", "", "");
            foreach (DataSetOilManagement.StoresRow row in data.DsOil.Stores)
            {
                dataSetOilManagement.Stores.Rows.Add(row.ItemArray);
            }
            //cbStores.EditValue = allStores;
        }

        public void updateProducts()
        {
            if (data == null)
                return;
            gridReport.BeginUpdate();

            productList.Clear();
            productNames.Clear();
            dataSource.Columns.Clear();
            gvReport.Columns.Clear();
            gvReport.Bands.Clear();

            dataSource.Columns.Add("Date", typeof(DateTime)).Caption = "Ngày";

            DevExpress.XtraGrid.Views.BandedGrid.GridBand band = gvReport.Bands.AddBand("");
            DevExpress.XtraGrid.Views.BandedGrid.BandedGridColumn col = gvReport.Columns.AddField("Date");
            col.Visible = true;
            col.OwnerBand = band;

            foreach (DataSetOilManagement.ProductsRow row in data.DsOil.Products)
            {
                if (row.IsNull(data.DsOil.Products.TypeColumn) || reportType == InOutReportType.ReceiptType)
                {
                    band = gvReport.Bands.AddBand(row.ProductName);
                    dataSource.Columns.Add("Import" + row.ProductName, typeof(decimal)).Caption = "Nhập " + row.ProductName;
                    dataSource.Columns.Add("Total" + row.ProductName, typeof(decimal)).Caption = "Lũy kế " + row.ProductName;

                    col = gvReport.Columns.AddField("Import" + row.ProductName);
                    col.ColumnEdit = AmountEdit;
                    if (reportType == InOutReportType.InType)
                    {
                        col.Caption = "Nhập";
                    }
                    else
                    {
                        col.Caption = "Xuất";
                    }

                    col.Visible = true;
                    band.Columns.Add(col);
                    col = gvReport.Columns.AddField("Total" + row.ProductName);
                    col.ColumnEdit = AmountEdit;
                    col.Caption = "Lũy kế";
                    col.Visible = true;
                    band.Columns.Add(col);

                    productList.Add(row.ID);
                    productNames[row.ID] = row.ProductName; 
                }
            }
            dataSource.Columns.Add("Total", typeof(decimal)).Caption = "Tổng lũy kế";
            band = gvReport.Bands.AddBand("");
            col = gvReport.Columns.AddField("Total");
            col.ColumnEdit = AmountEdit;
            band.Columns.Add(col);
            col.Visible = true;
            bindingSource.DataSource = dataSource;


            customizeGUIReport();

            updateProductforPrintReport();
            gridReport.EndUpdate();
        }

        private void customizeGUIReport()
        {
            //gvReport.PopulateColumns();
            if (gvReport.Columns.Count > 0)
            {
                gvReport.Columns[0].ColumnEdit = DateEdit;                
            }
            for (int i = 1; i < gvReport.Columns.Count - 1; i++)
            {
                if ((i - 1) % 4 < 2)
                {
                    gvReport.Columns[i].AppearanceCell.BackColor = Color.Silver;
                }
            }            
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            //coloringReport();
            UpdateReport();
        }

        private void InOutReport_Load(object sender, EventArgs e)
        {

            cbMonth.EditValue = DateTime.Now.Month;
            cbYear.EditValue = DateTime.Now.Year;
            //cbStores.ItemIndex = 0;
        }

        private void OptionChanged(object sender, EventArgs e)
        {
            UpdateReport();
            customizeGUIReport();
        }

        private XRLabel newPrintXRLabel(int position, Guid item, XRLabel sample)
        {
            XRLabel newlabel = new XRLabel();

            try
            {
                newlabel.Name = sample.Name + productNames[item];
            }
            catch (Exception)
            {
            }
            newlabel.BackColor = sample.BackColor;
            newlabel.Borders = sample.Borders;
            newlabel.Font = sample.Font;
            newlabel.Padding = sample.Padding;
            newlabel.SizeF = sample.SizeF;
            newlabel.StylePriority.UseBackColor = sample.StylePriority.UseBackColor;
            newlabel.StylePriority.UseBorders = sample.StylePriority.UseBackColor;
            newlabel.StylePriority.UseFont = sample.StylePriority.UseBackColor;
            newlabel.StylePriority.UseTextAlignment = sample.StylePriority.UseBackColor;

            //newlabel.Text = labels[item].Text;
            newlabel.LocationF = sample.LocationF;
            newlabel.LeftF += position * sample.WidthF;

            newlabel.TextAlignment = sample.TextAlignment;
            //printReport.Detail.Controls.Add(newlabel);
            newlabel.Visible = true;
            return newlabel;
        }

        public void updateProductforPrintReport()
        {
            foreach (XRLabel item in printHeaders.Values)
            {
                printReport.PageHeader.Controls.Remove(item);
            }
            printHeaders.Clear();

            foreach (XRLabel item in printHeadersLv2LuyKe.Values)
            {
                printReport.PageHeader.Controls.Remove(item);
            }
            printHeadersLv2LuyKe.Clear();

            foreach (XRLabel item in printHeadersLv2Nhap.Values)
            {
                printReport.PageHeader.Controls.Remove(item);
            }
            printHeadersLv2Nhap.Clear();

            foreach (XRLabel item in printDataNhap.Values)
            {
                printReport.Detail.Controls.Remove(item);
            }
            printDataNhap.Clear();
            foreach (XRLabel item in printDataLuyKe.Values)
            {
                printReport.Detail.Controls.Remove(item);
            }
            printDataLuyKe.Clear();

            string storeName = "";
            string typeName = "NHẬP";
            if (cbStores.EditValue != null && (Guid)cbStores.EditValue != allStores)
            {
                storeName = cbStores.Text;
            }
            if (reportType == InOutReportType.OutType)
	        {
                typeName = "XUẤT";
	        }
            else if (reportType == InOutReportType.ReceiptType)
            {
                typeName = "HÓA ĐƠN";
            }


            printReport.txtTitle.Text = string.Format("THỐNG KÊ {0} {1} tháng {2} năm {3}", typeName, storeName, cbMonth.EditValue, cbYear.EditValue);

            XRLabel newlabel = null;
            int count = 0;
            printReport.txtHeaderlv1.HeightF = printReport.txtHeaderlv2.HeightF;
            printReport.txtHeaderlv1.WidthF = (printReport.PageWidth - printReport.Margins.Left - printReport.Margins.Right) / (productList.Count + 2);
            printReport.txtHeaderlv2B.WidthF = printReport.txtHeaderlv1.WidthF / 2;
            printReport.txtHeaderlv2.WidthF = printReport.txtHeaderlv1.WidthF / 2;
            printReport.txtHeaderlv2.LeftF = printReport.txtHeaderlv1.WidthF / 2;
            printReport.txtDataDate.WidthF = printReport.txtHeaderlv1.WidthF;
            printReport.txtDataSample.WidthF = printReport.txtHeaderlv2.WidthF;
            printReport.txtDataSample.LeftF = printReport.txtHeaderlv2.LeftF;
            printReport.txtDataDate.DataBindings.Clear();
            printReport.txtDataDate.DataBindings.Add("Text", dataSource, "Date", "{0:dd/MM}");
            foreach (Guid item in productList)
            {
                count++;
                newlabel = newPrintXRLabel(count, item, printReport.txtHeaderlv1);
                newlabel.Text = productNames[item];
                printReport.PageHeader.Controls.Add(newlabel);
                printHeaders[item] = newlabel;

                newlabel = newPrintXRLabel(count*2-1, item, printReport.txtHeaderlv2);
                newlabel.Text = "Nhập";
                printReport.PageHeader.Controls.Add(newlabel);
                printHeadersLv2Nhap[item] = newlabel;

                newlabel = newPrintXRLabel(count * 2 - 1, item, printReport.txtDataSample);
                newlabel.DataBindings.Add("Text", dataSource, "Import" + productNames[item], "{0:N0}");
                printReport.Detail.Controls.Add(newlabel);
                printDataNhap[item] = newlabel;


                newlabel = newPrintXRLabel(count * 2, item, printReport.txtHeaderlv2);
                newlabel.Text = "Lũy kế";
                printReport.PageHeader.Controls.Add(newlabel);
                printHeadersLv2Nhap[item] = newlabel;

                newlabel = newPrintXRLabel(count * 2, item, printReport.txtDataSample);
                newlabel.DataBindings.Add("Text", dataSource, "Total" + productNames[item], "{0:N0}");
                printReport.Detail.Controls.Add(newlabel);
                printDataLuyKe[item] = newlabel;
            }
            count++;
            newlabel = newPrintXRLabel(count, allStores, printReport.txtHeaderlv1);
            newlabel.Name = "labelTongluyke";
            newlabel.Text = "Tổng lũy kế";
            newlabel.HeightF = 2 * printReport.txtHeaderlv2.HeightF;
            printReport.PageHeader.Controls.Add(newlabel);
            printHeaders[allStores] = newlabel;

            newlabel = newPrintXRLabel(count, allStores, printReport.txtDataDate);
            newlabel.Name = "txtTotal";
            newlabel.DataBindings.Add("Text", dataSource, "Total", "{0:N0}");
            printReport.Detail.Controls.Add(newlabel);
            printDataNhap[allStores] = newlabel;


            printReport.txtHeaderlv1.HeightF = printReport.txtHeaderlv2.HeightF * 2;
        }

        public void printPreView()
        {
            updateProductforPrintReport();
            printReport.DataSource = dataSource;
            printReport.CreateDocument();
            printReport.ShowPreview();
        }

        private void simpleButton1_Click_1(object sender, EventArgs e)
        {
            printPreView();
        }
    }
}
